package com.hyk.commonLib.common.utils;

import android.text.TextUtils;

import java.io.ByteArrayOutputStream;
import java.math.BigInteger;

/**
 * Created by 贺玉琨 on 2019/6/4.
 */

public class RadixConverter {
    private static final String hexString = "0123456789ABCDEF";

    /**
     * 将二进制转换成16进制
     *
     * @param buf
     * @return String
     */
    public static String byteToHexStr(byte[] buf) {
        StringBuilder sb = new StringBuilder();
        for (byte b : buf) {
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将16进制转换为二进制
     *
     * @param hexStr
     * @return byte[]
     */
    public static byte[] hexStrToByte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    public static String binaryToHexStr(String sBinary) {
        StringBuilder sbuf = new StringBuilder();
        int blength = sBinary.length() % 4;
        if (blength != 0) {
            String first = sBinary.substring(0, blength);
            sbuf.append(Integer.toHexString(Integer.parseInt(first, 2)));
            sBinary = sBinary.substring(blength);
        }
        int cnum = sBinary.length() / 4;
        for (int i = 0; i < cnum; i++) {
            sbuf.append(Integer.toHexString(Integer.parseInt(sBinary.substring(i * 4, 4 * (i + 1)), 2)));
        }
        return "0x" + sbuf.toString().toUpperCase();
    }

    public static String hexToBinaryStr(String sHex) {
        StringBuilder sbuf = new StringBuilder();
        for (int i = 0; i < sHex.length(); i++) {
            String bin = Integer.toBinaryString(Integer.parseInt(sHex.substring(i, i + 1), 16));
            if (i > 0) {
                bin = "0000" + bin;
                bin = bin.substring(bin.length() - 4);
            }
            sbuf.append(bin);
        }
        return sbuf.toString();
    }

    public static String toHexStr(String s) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str.append(s4);
        }
        return str.insert(0, "0x").toString();// 0x表示十六进制
    }

    public static byte[] stringToByte(String s) {
        byte[] output = new byte[s.length()];
        for (int i = 0; i < s.length(); i++) {
            output[i] = Byte.parseByte(String.valueOf(i));
        }
        return output;
    }

    public static String getHexStr(byte[] b) {
        StringBuilder result = new StringBuilder();
        for (byte value : b) {
            result.append(Integer.toString((value & 0xff) + 0x100, 16).substring(1));
        }
        return result.toString();
    }

    public static byte[] getByteArray(String hexString) {
        return new BigInteger(hexString, 16).toByteArray();
    }

    public static String binaryToHexStr(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        String hex = "";
        String hexStr = "0123456789ABCDEF";
        for (byte aByte : bytes) {
            // 字节高4位
            hex = String.valueOf(hexStr.charAt((aByte & 0xF0) >> 4));
            // 字节低4位
            hex += String.valueOf(hexStr.charAt(aByte & 0x0F));
            result.append(hex);
        }
        return result.toString();
    }

    /*
     * 将字符串编码成16进制数字,适用于所有字符（包括中文）
     */
    public static String stringToHexStr(String strPart) {
        StringBuilder hexString = new StringBuilder();
        for (int i = 0; i < strPart.length(); i++) {
            int ch = (int) strPart.charAt(i);
            String strHex = Integer.toHexString(ch);
            hexString.append(strHex);
        }
        return hexString.toString();
    }

    /*
     * 将字符串编码成16进制数字,适用于所有字符（包括中文）
     */
    public static String encodeAsciiStrToHex(String str) {
        // 根据默认编码获取字节数组
        byte[] bytes = str.getBytes();
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        // 将字节数组中每个字节拆解成2位16进制整数
        for (byte aByte : bytes) {
            sb.append(hexString.charAt((aByte & 0xf0) >> 4));
            sb.append(hexString.charAt((aByte & 0x0f)));
        }
        return sb.toString();
    }

    /*
     * 将16进制数字解码成字符串,适用于所有字符（包括中文）
     */
    public static String decodeHexToAsciiStr(String bytes) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(
                bytes.length() / 2);
        // 将每2位16进制整数组装成一个字节
        for (int i = 0; i < bytes.length(); i += 2)
            baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString.indexOf(bytes.charAt(i + 1))));
        return new String(baos.toByteArray());
    }

    private static byte uniteBytes(byte src0, byte src1) {
        byte _b0 = Byte.decode("0x" + new String(new byte[]{src0}));
        _b0 = (byte) (_b0 << 4);
        byte _b1 = Byte.decode("0x" + new String(new byte[]{src1}));
        return (byte) (_b0 | _b1);
    }

    public static byte[] hexTobytes(String hex) {
        String digital = "0123456789ABCDEF";
        char[] hex2char = hex.toCharArray();
        byte[] bytes = new byte[hex.length() / 2];
        int temp;
        for (int i = 0; i < bytes.length; i++) {
            temp = digital.indexOf(hex2char[2 * i]) * 16;
            temp += digital.indexOf(hex2char[2 * i + 1]);
            bytes[i] = (byte) (temp & 0xff);
        }
        return bytes;
    }

    /*
     * Convert byte[] to hex
     * string.这里我们可以将byte转换成int，然后利用Integer.toHexString(int)来转换成16进制字符串。
     *
     * @param src byte[] data
     *
     * @return hex string
     */
    public static String bytesToHexStr(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte b : src) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString().toUpperCase().trim();
    }

    /**
     * Convert hex string to byte[]
     *
     * @param hexString the hex string
     * @return byte[]
     */
    public static byte[] hexStrToBytes(String hexString) {
        if (TextUtils.isEmpty(hexString)) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * Convert char to byte
     *
     * @param c char
     * @return byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
}